package Thread_;

/**
 * 单例模式
 * 懒汉式
 */
class InstanceLazy1{
    private volatile static InstanceLazy1 single=null;
    private InstanceLazy1(){}
    public static InstanceLazy1 getInstance(){
        Object locker=new Object();
        if(single==null){
            synchronized(locker){
                if(single==null){
                    single=new InstanceLazy1();
                }
            }
        }
        return single;
    }
}

/**
 * 单例模式
 * 饿汉式 优化版
 */
class InstanceLazy{
    // 定义该类对象，设为私有，静态
    // 先不实例化对象 将其设为null
    //优化3：为防止在创建类对象的时候 出现 指令重排序问题，出现线程安全问题
    // 给single对象 加volatile关键字,底层不再进行指令重排序
    private static volatile InstanceLazy single=null;
    //将构造器私有化
    private InstanceLazy(){}
    private static Object locker=new Object();
    //提供获取对象的公共方法，在方法内创建对象
    public static InstanceLazy getInstance(){
        //判断
        // 若还未实例化对象，就实例化对象，
        if(single==null){//优化2：当第一次创建后，之后就不用再判断了，也就不用再加锁了，
                        //为了提高代码的效率，先判断一下，若不为空，则不再加锁，直接返回对象
            synchronized(locker){//懒汉式 优化1 ：为防止出现线程安全问题
                                //将判断为空和创建新线程，设置为一个 原子的
                if(single==null){
                    single=new InstanceLazy();//将类对象创建出来
                }
            }
        }
        //若已创建过对象，就直接返回创建过的对象
        return single;
    }
}
public class Thread18 {
    public static void main(String[] args) {
        InstanceLazy single1=InstanceLazy.getInstance();
        InstanceLazy single2=InstanceLazy.getInstance();
        InstanceLazy single3=InstanceLazy.getInstance();
        System.out.println(single3==single2);//true single1和single2是同一个对象
    }
}
